package za.org.foobar.famon.reporter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import za.org.foobar.famon.util.Util;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import java.util.Set;

/**
 * A helper class to load properties into the famon reporter.
 */
public class FamonReporterProperties {
    public static final String DEFAULT_PROPERTIES_FILE = "/famon-reporter-default.properties";
    private final Log log = LogFactory.getLog(getClass());

    public void loadProperties(FamonReporterLogic logic, boolean loadDefaultProperties) {
        if (loadDefaultProperties) {
            URL url = FamonReporterLogic.class.getResource(DEFAULT_PROPERTIES_FILE);
            if (url == null) {
                log.error("Could not open the default properties file: " + DEFAULT_PROPERTIES_FILE);
                return;
            }

            log.info("Reading properties from \"" + url.getFile() + "\"");
            try {
                loadProperties(logic, url.openStream());
            } catch (IOException e) {
                log.error("Could not open resource url stream: " + url.getFile(), e);
            }
        }
    }

    public void loadProperties(FamonReporterLogic logic, String propertiesFile) {
        log.info("Reading properties from \"" + propertiesFile + "\"");
        try {
            loadProperties(logic, new FileInputStream(propertiesFile));
        } catch (IOException e) {
            log.error("Could not open or read properties file: " + propertiesFile, e);
            return;
        }
    }

    public void loadProperties(FamonReporterLogic logic, InputStream propertiesInputStream) throws IOException {
        log.info("Reporter: " + this + ", Thread: " + Thread.currentThread().getName());
        // Read properties file.
        Properties properties = new Properties();
        properties.load(propertiesInputStream);

        Set<String> set =  properties.stringPropertyNames();
        if (log.isDebugEnabled()) {
            for (String s : set) {
                log.debug("Prop[" + s + "] = " + properties.getProperty(s));
            }
        }
        logic.setServer(properties.getProperty("famon.server", logic.getServer()));
        logic.setApplication(properties.getProperty("famon.application", logic.getApplication()));
        logic.setInstance(properties.getProperty("famon.instance", logic.getInstance()));
        logic.setUserValue(properties.getProperty("famon.user"));
        logic.setUserGetter(properties.getProperty("famon.user.getter"));
        logic.setVersionValue(properties.getProperty("famon.version"));
        logic.setVersionGetter(properties.getProperty("famon.version.getter"));
        logic.setSendIpAndHostname(Boolean.parseBoolean(properties.getProperty("famon.sendIpAndHostname", Boolean.toString(logic.isSendIpAndHostname()))));
        logic.setServerTimeoutSeconds(Integer.parseInt(properties.getProperty("famon.timeoutSeconds", Integer.toString(logic.getServerTimeoutSeconds()))));
        logic.setLog4jAppender(Integer.parseInt(properties.getProperty("famon.appender.log4jAppenderSize", Integer.toString(10))));
        logic.setFailureHistorySize(Integer.parseInt(properties.getProperty("famon.failureHistorySize", Integer.toString(logic.getFailureHistorySize()))));
        logic.setExcludeDuplicates(Boolean.parseBoolean(properties.getProperty("famon.excludeDuplicates", Boolean.toString(logic.isExcludeDuplicates()))));
        logic.setDuplicateThresholdMs(Integer.parseInt(properties.getProperty("famon.duplicateThresholdMs", Integer.toString(logic.getDuplicateThresholdMs()))));

        String processorName = properties.getProperty("famon.processor");
        if (processorName != null) {
            logic.setWorkProcessorByName(processorName);
            FamonWorkProcessor processor = logic.getWorkProcessor();
            if (processor instanceof FamonThreadPoolWorkProcessor) {
                FamonThreadPoolWorkProcessor p = (FamonThreadPoolWorkProcessor)processor;
                p.setThreadPoolCount(Integer.parseInt(properties.getProperty("famon.processor.threadPoolCount", Integer.toString(p.getThreadPoolCount()))));
            } else if (processor instanceof FamonSynchronousWorkProcessor) {
                // FamonSynchronousWorkProcessor p = new FamonSynchronousWorkProcessor();
            } else if (processor instanceof FamonFileBufferWorkProcessor) {
                FamonFileBufferWorkProcessor p = new FamonFileBufferWorkProcessor();
                p.setBufferFile(Util.emptyAsNull(properties.getProperty("famon.processor.bufferFile", p.getBufferFile())));
                p.setFailuresPerBatch(Math.max(Integer.parseInt(properties.getProperty("famon.processor.failuresPerBatch", Integer.toString(p.getFailuresPerBatch()))), 1));
                p.setSecondsBetweenReports(Integer.parseInt(properties.getProperty("famon.processor.secondsBetweenReports", Integer.toString(p.getSecondsBetweenReports()))));
                p.setPollSleepSeconds(Integer.parseInt(properties.getProperty("famon.processor.poll.sleepSeconds", Integer.toString(p.getPollSleepSeconds()))));
                p.setPollStartTime(Integer.parseInt(properties.getProperty("famon.processor.poll.startTime", Integer.toString(p.getPollStartTime()))));
                p.setPollDurationMinutes(Integer.parseInt(properties.getProperty("famon.processor.poll.durationMinutes", Integer.toString(p.getPollDurationMinutes()))));
            }
        }
    }
}
